import {Websock} from './websock'
import {chatEvents} from '../chatEvents'
import EventEmitter from '../../common/EventEmitter'
export default class XchatWebsocket{
	constructor(wb_param = null,xchat_protocol = {}) {
	  this.wb_param = wb_param
		this.xchat_protocol = xchat_protocol
		this.init()
	}
	init(){
		this.ws = null
		this.error_count = 0
		this.heartbeat_ref = null
		this.emitter = new EventEmitter()
		this.passport = '0'
		console.log(">> connect")
		if((!this.wb_param.ip) || (!this.wb_param.port)){
			console.error('must set ip and port')
			throw new Error('websocket must set ip and port!')
		}
		if(this.ws){
			this.ws.close()
		}
		this.connectWb()
	}
	reconnect(){
		this.connectWb()
	}
	connectWb(){
		const scheme = "ws://"
		const uri =  scheme + this.wb_param.ip + ":" + this.wb_param.port + "/websockify"
		this.ws = new Websock()
		this.ws.open(uri)
		if(this.heartbeat_ref === null){
			this.heartbeat_ref = setInterval(this.heartbeat.bind(this), 1000*15)
		}
		this.ws.on('message', ()=>{
			this.do_recv()
		})
		this.ws.on('open', this.do_open.bind(this))
		this.ws.on('close', this.do_error.bind(this))
	}
	do_open(e) {
		console.log(">> WebSockets.onopen");
		this.error_count = 0;
		//send login packet
		let login_timer = setInterval(()=>{
			if(this.ws.get_state() == 1){
				if("packet_login" in this.xchat_protocol){
					this.ws.send(this.xchat_protocol.packet_login(this.wb_param.room_id,this.wb_param.uid,this.wb_param.level,this.wb_param.appdata,this.wb_param.token))
				}
				clearInterval(login_timer)
			}
		},1000);
	}
	do_error(e){
		this.xchat_protocol.logined = false
		this.error_count += 1;
		if (this.error_count>5){
			this.emitter.trigger(chatEvents.MSG_SOCKET_ERROR)
			return;
		}
		if (!this.xchat_protocol.Closed_By_Server){
			if (this.xchat_protocol.passport !== '0'){
				console.log('do_error. ' + Date.now()/1000);
				setTimeout(this.reconnect.bind(this),3000);
			}
			else{
				this.emitter.trigger(chatEvents.MSG_SOCKET_ERROR)
			}
		}
	}
	heartbeat() {
		if (this.ws && this.ws.get_state() == 1 && this.xchat_protocol.logined){
			this.ws.send(this.xchat_protocol.packet_heartbeat());
		}
	}
	logout(){
		if (this.ws) {
			this.ws.on('close', function(){});
			this.ws.send(this.xchat_protocol.packet_logout());
			this.ws.close()
		}
	}
	do_recv(){
		while(1){
			if (this.xchat_protocol.packet_fetch_state == 0){
				if(this.ws.rQlen() >= 4){
					this.xchat_protocol.packet_header = this.ws.rQshiftBytes(4);
					this.xchat_protocol.parse_header();
					this.xchat_protocol.packet_fetch_state = 1
				}
				else{
					break;
				}
			}
			else{
				if (this.ws.rQlen() >= this.xchat_protocol.packet_body_length){
					this.xchat_protocol.packet_body = this.ws.rQshiftBytes(this.xchat_protocol.packet_body_length)
					this.xchat_protocol.packet_fetch_state = 0
					this.xchat_protocol.process_packet(this.emitter,chatEvents)
				}
				else{
					break;
				}
			}
		}
	}
	on(event, listener) {
		this.emitter.on(event, listener)
	}
	off(event, listener) {
		this.emitter.off(event, listener)
	}
}